package services

import (
	"errors"
	"game-server/app/common/enum"
	"game-server/app/common/request"
	"game-server/app/common/response"
	"game-server/app/models"
	"game-server/global"

	"gorm.io/gorm"
)

type gameService struct{}

var GameService = new(gameService)

// 分页获取游戏列表
func (s *gameService) GetGameList(params request.GameListRequest) (response.ListResponse[models.Game], error) {
	var res response.ListResponse[models.Game]
	var games []models.Game

	query := global.App.DB.Model(&models.Game{})

	// 条件查询
	if params.Name != "" {
		query = query.Where("name LIKE ?", "%"+params.Name+"%")
	}
	if params.CategoryID != nil {
		query = query.Where("category_id = ?", *params.CategoryID)
	}
	// tagsID
	if params.TagsID != 0 {
		query = query.Where("id =?", params.TagsID)
	}
	if params.Status != nil {
		query = query.Where("status = ?", *params.Status)
	}
	if params.StartTime != "" {
		query = query.Where("created_at >= ?", params.StartTime)
	}
	if params.EndTime != "" {
		query = query.Where("created_at <= ?", params.EndTime)
	}
	if params.IsNewHotRecommend != nil {
		if *params.IsNewHotRecommend == enum.IsHotParams {
			query = query.Where("is_hot = ?", enum.Enabled)
		} else if *params.IsNewHotRecommend == enum.IsNewParams {
			query = query.Where("is_new = ?", enum.Enabled)
		} else if *params.IsNewHotRecommend == enum.IsRecommendParams {
			query = query.Where("is_recommend = ?", enum.Enabled)
		}
	}
	// 根据tagId查询游戏
	if params.TagsID != 0 {
		query = query.Joins("JOIN game_tags ON game_tags.game_id = games.id").
			Where("game_tags.tag_id =?", params.TagsID)
	}

	// 获取总数
	query.Count(&res.Total)

	// 分页查询
	offset := (params.Page - 1) * params.PageSize
	err := query.Offset(offset).
		Limit(params.PageSize).
		Order("id DESC").
		Find(&games).Error

	if err != nil {
		return res, err
	}
	// 获取游戏标签
	for i := range games {
		var tags []models.Tag
		if err := global.App.DB.Model(&games[i]).Association("Tags").Find(&tags); err != nil {
			return res, err
		}
		games[i].Tags = tags
	}
	// 获取游戏截图
	for i := range games {
		var images []models.ScreenShot
		//where game_id =?
		global.App.DB.Where("game_id =?", games[i].ID.ID).Find(&images)
		games[i].ScreenShots = images
	}
	// 获取游戏视频
	for i := range games {
		var videos []models.GameVideo
		//where game_id = ?
		global.App.DB.Where("game_id =?", games[i].ID.ID).Find(&videos)
		games[i].GameVideos = videos
	}

	// 获取游戏分类
	for i := range games {
		var category models.Category
		if err := global.App.DB.First(&category, games[i].CategoryId).Error; err != nil {
			return res, err
		}
		games[i].Category = category
	}
	res.List = games

	return res, nil
}

// 新增游戏
func (s *gameService) CreateGame(params request.GameAddRequest) error {
	return global.App.DB.Transaction(func(tx *gorm.DB) error {
		// 检查分类是否存在
		var category models.Category
		if err := tx.First(&category, params.CategoryId).Error; err != nil {
			return errors.New("分类不存在")
		}

		// 检查游戏名称是否重复
		var count int64
		tx.Model(&models.Game{}).Where("name = ?", params.Name).Count(&count)
		if count > 0 {
			return errors.New("游戏名称已存在")
		}

		// 创建游戏基本信息
		game := models.Game{
			Name:      params.Name,
			Icon:      params.Icon,
			GameUrl:   params.GameUrl,
			Desc:      params.Desc,
			Image:     params.Image,
			Introduce: params.Introduce,
			Width:     params.Width,
			Height:    params.Height,
			Status:    params.Status,
			Category:  category,

			CategoryId:  params.CategoryId,
			IsNew:       params.IsNew | enum.Disabled, //params.IsNew || enum.Disabled
			IsRecommend: params.IsRecommend | enum.Disabled,
			IsHot:       params.IsHot | enum.Disabled,
			Sort:        params.Sort | enum.Disabled,
			Click:       params.Click | 1,
		}

		if err := tx.Create(&game).Error; err != nil {
			return errors.New("创建游戏基本信息失败")
			// return err
		}

		// 处理标签
		for _, tagName := range params.Tags {
			var tag models.Tag
			// 查找或创建标签
			if err := tx.FirstOrCreate(&tag, models.Tag{
				Name: tagName.Name,
			}).Error; err != nil {
				// return errors.New("创建标签失败")
				return err
			}
			// 关联游戏和标签
			if err := tx.Create(&models.GameTag{
				GameId: game.ID.ID,
				TagId:  tag.ID.ID,
			}).Error; err != nil {
				// return errors.New("创建游戏标签关联失败")
				return err
			}
		}

		// 创建截图
		for _, image := range params.ScreenShots {
			if err := tx.Create(&models.ScreenShot{
				Image:  image.Image,
				GameId: game.ID.ID,
			}).Error; err != nil {
				// return errors.New("创建截图失败")
				return err
			}
		}

		// 创建视频
		for _, video := range params.GameVideos {
			if err := tx.Create(&models.GameVideo{
				Video:  video.Video,
				GameId: game.ID.ID,
			}).Error; err != nil {
				// return errors.New("创建视频失败")
				return err
			}
		}

		return nil
	})
}

// 删除游戏
func (s *gameService) DelGame(form request.GameDelRequest) error {
	id := form.ID
	return global.App.DB.Transaction(func(tx *gorm.DB) error {
		// 删除游戏基本信息
		if err := tx.Delete(&models.Game{}, form.ID).Error; err != nil {
			return err
		}
		// 删除游戏标签关联
		if err := tx.Where("game_id =?", id).Delete(&models.GameTag{}).Error; err != nil {
			return err
		}
		// 删除游戏截图
		if err := tx.Where("game_id =?", id).Delete(&models.ScreenShot{}).Error; err != nil {
			return err
		}
		// 删除游戏视频
		if err := tx.Where("game_id =?", id).Delete(&models.GameVideo{}).Error; err != nil {
			return err
		}
		return nil
	})
}

// BatchDelGame 批量删除游戏
func (s *gameService) BatchDelGame(form request.GameBatchDelRequest) error {
	return global.App.DB.Transaction(func(tx *gorm.DB) error {
		// 删除游戏基本信息
		if err := tx.Where("id IN ?", form.IDS).Delete(&models.Game{}).Error; err != nil {
			return err
		}
		// 删除游戏标签关联
		if err := tx.Where("game_id IN?", form.IDS).Delete(&models.GameTag{}).Error; err != nil {
			return err
		}
		// 删除游戏截图
		if err := tx.Where("game_id IN?", form.IDS).Delete(&models.ScreenShot{}).Error; err != nil {
			return err

		}
		// 删除游戏视频
		if err := tx.Where("game_id IN?", form.IDS).Delete(&models.GameVideo{}).Error; err != nil {
			return err
		}
		return nil
	})

}

// UpdateGame 更新游戏
func (s *gameService) UpdateGame(form request.GameUpdateRequest) error {
	return global.App.DB.Transaction(func(tx *gorm.DB) error {
		// 检查游戏是否存在
		var game models.Game
		if err := tx.First(&game, form.ID).Error; err != nil {
			return errors.New("游戏不存在")
		}
		// 更新游戏基本信息
		game.Name = form.Name
		game.Icon = form.Icon
		game.GameUrl = form.GameUrl
		game.Desc = form.Desc
		game.Image = form.Image
		game.Introduce = form.Introduce
		game.Width = form.Width
		game.Height = form.Height
		game.Status = form.Status
		game.IsRecommend = form.IsRecommend
		game.IsHot = form.IsHot
		game.Sort = form.Sort
		game.IsNew = form.IsNew

		if err := tx.Save(&game).Error; err != nil {
			return err
		}
		// 更新游戏标签
		if err := tx.Where("game_id =?", form.ID).Delete(&models.GameTag{}).Error; err != nil {
			return err
		}
		for _, tagName := range form.Tags {
			var tag models.Tag
			// 查找或创建标签
			if err := tx.FirstOrCreate(&tag, models.Tag{
				Name: tagName.Name,
			}).Error; err != nil {
				return err
			}
			// 关联游戏和标签
			if err := tx.Create(&models.GameTag{
				GameId: game.ID.ID,
				TagId:  tag.ID.ID,
			}).Error; err != nil {
				return err
			}
		}
		// 更新游戏截图
		if err := tx.Where("game_id =?", form.ID).Delete(&models.ScreenShot{}).Error; err != nil {
			return err
		}
		for _, image := range form.ScreenShots {
			if err := tx.Create(&models.ScreenShot{
				Image:  image.Image,
				GameId: form.ID,
			}).Error; err != nil {
				return err
			}
		}
		// 更新游戏视频
		if err := tx.Where("game_id =?", form.ID).Delete(&models.GameVideo{}).Error; err != nil {
			return err
		}
		for _, video := range form.GameVideos {
			if err := tx.Create(&models.GameVideo{
				Video:  video.Video,
				GameId: form.ID,
			}).Error; err != nil {
				return err
			}
		}
		return nil
	})
}

// UpdateGameClick 更新游戏点击量
func (s *gameService) UpdateGameClick(id uint) error {
	return global.App.DB.Transaction(func(tx *gorm.DB) error {
		// 更新点击量，使用原生 SQL 来实现原子递增
		if err := tx.Exec("UPDATE games SET click = click + 1 WHERE id = ?", id).Error; err != nil {
			return err
		}
		return nil
	})
}

// GetGameDetail 门户-id获取游戏详情
func (s *gameService) GetGameDetail(id uint) (*models.Game, error) {
	var game models.Game

	err := global.App.DB.Model(&models.Game{}).
		Preload("Tags").
		Preload("ScreenShots").
		Preload("GameVideos").
		Preload("Category").
		First(&game, id).Error

	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, errors.New("游戏不存在")
		}
		return nil, err
	}

	return &game, nil
}
